package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huiminpay.common.cache.Cache;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.transaction.api.dto.PayChannelDTO;
import com.huiminpay.transaction.api.dto.PayChannelParamDTO;
import com.huiminpay.transaction.api.dto.PlatformChannelDTO;
import com.huiminpay.transaction.api.service.PlatformChannelServiceApi;
import com.huiminpay.transaction.common.util.RedisUtil;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.convert.PlatformChannelConvert;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.entity.PlatformChannel;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import com.huiminpay.transaction.mapper.PlatformChannelMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
@Service
@Slf4j
public class PlatformChannelServiceImpl implements PlatformChannelServiceApi {

    @Autowired
    private PlatformChannelMapper platformChannelMapper;
    @Autowired
    private AppPlatformChannelMapper appPlatformChannelMapper;
    @Autowired
    private PayChannelMapper payChannelMapper;
    @Autowired
    private PayChannelParamMapper payChannelParamMapper;
    @Autowired
    private Cache cache;

    /**
     * 获取平台服务类型列表
     * @return
     */
    @Override
    public List<PlatformChannelDTO> findAllPlatformChannel() {
        List<PlatformChannel> platformChannelList = platformChannelMapper.selectList(null);
        List<PlatformChannelDTO> platformChannelDTOList = PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannelList);
        return platformChannelDTOList;
    }

    /**
     * 为应用绑定服务类型
     * @param appId
     * @param platformChannelCode
     */
    @Override
    public void bindPlatformChannelForApp(String appId, String platformChannelCode) throws BusinessException {
        //非空校验
        if (appId == null || platformChannelCode == null) {
            throw new BusinessException(CommonErrorCode.E_110006);
        }
        AppPlatformChannel apfChannel = findAppPlatformChannelByIdAndCode(appId, platformChannelCode);
        if (apfChannel!=null){
            //应用已绑定平台服务
            throw new BusinessException(CommonErrorCode.E_110006);
        }
        AppPlatformChannel appPlatformChannel = new AppPlatformChannel();
        appPlatformChannel.setAppId(appId);
        appPlatformChannel.setPlatformChannel(platformChannelCode);
        appPlatformChannelMapper.insert(appPlatformChannel);
    }

    /**
     * 查看应用是否已绑定该服务类型
     * @param appId
     * @param platformChannelCode
     * @return
     */
    @Override
    public String existBindPlatformForApp(String appId, String platformChannelCode) throws BusinessException {
        AppPlatformChannel appPlatformChannel = findAppPlatformChannelByIdAndCode(appId, platformChannelCode);
        if (appPlatformChannel == null) {
            return "NO";
        }
        return "YES";
    }

    /**
     * 根据appId、platformChannelCode获取应用平台服务类型
     * @param appId
     * @param platformChannelCode
     * @return
     */
    private AppPlatformChannel findAppPlatformChannelByIdAndCode(String appId, String platformChannelCode) throws BusinessException {
        return appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>()
                .eq(AppPlatformChannel::getAppId, appId).eq(AppPlatformChannel::getPlatformChannel, platformChannelCode));
    }



    //==========================================



    /**
     * 根据服务类型code查询第三方支付渠道列表信息
     * @param platformChannelCode
     * @return
     */
    @Override
    public List<PayChannelDTO> queryPayChannelByPlatformChannel(String platformChannelCode) throws BusinessException {
        //从缓存查询
        List<PayChannelDTO> payChannelByPlatformChannel = payChannelMapper.findPayChannelByPlatformChannel(platformChannelCode);
        return payChannelByPlatformChannel;
    }

    /**
     * 保存第三方支付渠道参数信息
     * @param payChannelParamDTO
     * @return
     */
    @Override
    public PayChannelParamDTO savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException {
        if (payChannelParamDTO == null || StringUtils.isBlank(payChannelParamDTO.getAppId())
                ||StringUtils.isBlank(payChannelParamDTO.getPlatformChannelCode())
                ||StringUtils.isBlank(payChannelParamDTO.getPayChannel())){
            throw new BusinessException(CommonErrorCode.E_110006);
        }
        //根据应用id和平台服务类型code获取应用绑定服务类型的id
        Long appPlatformChannelId = selectIdByAppPlatformChannel(payChannelParamDTO.getAppId(), payChannelParamDTO.getPlatformChannelCode());
        if (appPlatformChannelId == null) {
            throw new BusinessException(CommonErrorCode.E_110006);
        }
        //根据第三方支付渠道code和appPlatformChannelId查询PayChannelParam
        PayChannelParam payChannelParamDb = payChannelParamMapper.selectOne(new LambdaQueryWrapper<PayChannelParam>()
                .eq(PayChannelParam::getPayChannel, payChannelParamDTO.getPayChannel())
                .eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
        PayChannelParam payChannelParam = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);

        if (payChannelParamDb!=null){
            payChannelParam.setId(payChannelParamDb.getId());
            //更新配置信息
            payChannelParamMapper.updateById(payChannelParam);
        }else {
            //新增配置信息
            payChannelParamMapper.insert(payChannelParam);
        }
        payChannelParamDTO.setId(payChannelParam.getId());
        //将支付渠道参数信息放入redis缓存
        try {
            updateRedis(payChannelParamDTO.getAppId(),payChannelParamDTO.getPlatformChannelCode(),payChannelParamDTO.getPayChannel(),payChannelParamDTO);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return payChannelParamDTO;
    }

    //更新缓存
    private void updateRedis(String appId,String platformChannelCode,String payChannel,PayChannelParamDTO payChannelParamDTO){
        String redisKey = RedisUtil.keyBuilder(appId,platformChannelCode,payChannel);
        System.out.println("redisKey==============================="+redisKey);
        cache.set(redisKey, JSON.toJSONString(payChannelParamDTO));
    }


    /**
     * 根据应用、服务类型查询应用与服务类型的绑定id
     * @param appId
     * @param platformChannelCode
     * @return
     */
    private Long selectIdByAppPlatformChannel(String appId,String platformChannelCode){
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>().eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannelCode));
        if(appPlatformChannel!=null){
            return appPlatformChannel.getId();//应用与服务类型的绑定id
        }
        return null;
    }

    /**
     * 获取指定应用指定服务类型下所包含的某个原始支付参数
     * @param appId
     * @param platformChannel
     * @param payChannel
     * @return
     */
    @Override
    public PayChannelParamDTO queryParamByAppPlatformAndPayChannel(String appId, String platformChannel, String payChannel) {
        // 查询redis缓存
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel, payChannel);
        String payChannelParamDTO_String = cache.get(redisKey);
        try {
            if (!StringUtils.isEmpty(payChannelParamDTO_String)){
                PayChannelParamDTO payChannelParamDTO = JSON.parseObject(payChannelParamDTO_String, PayChannelParamDTO.class);
                return payChannelParamDTO;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        //根据应用id和平台服务类型code获取应用绑定服务类型的id
//        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId, platformChannel);
//        if (appPlatformChannelId == null) {
//            throw new BusinessException(CommonErrorCode.E_200202);
//        }
//        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(new LambdaQueryWrapper<PayChannelParam>()
//                .eq(PayChannelParam::getPayChannel, payChannel)
//                .eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
//        PayChannelParamDTO payChannelParamDTO = PayChannelParamConvert.INSTANCE.entity2dto(payChannelParam);
//
//        updateRedis(appId, platformChannel, payChannel, payChannelParamDTO);
//        return payChannelParamDTO;
        //根据应用id和平台服务类型code获取应用绑定服务类型的id
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>().eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannel));
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(new LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getPayChannel, payChannel)
                .eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannel.getId()));
        PayChannelParamDTO payChannelParamDTO = PayChannelParamConvert.INSTANCE.entity2dto(payChannelParam);

        updateRedis(appId,platformChannel,payChannel,payChannelParamDTO);
        return payChannelParamDTO;
    }


    /**
     * 获取指定应用指定服务类型下所包含的原始支付渠道参数列表
     * @param appId
     * @param platformChannel
     * @return
     * @throws BusinessException
     */
    @Override
    public List<PayChannelParamDTO> queryParamListByAppPlatformAndPayChannel(String appId, String platformChannel) throws BusinessException {
        //从缓存查询
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //判断缓存是否存在
        Boolean exists = cache.exists(redisKey);
        if (exists) {
            //从redis获取key对应的value
            String value = cache.get(redisKey);
            //将value转成对象
            List<PayChannelParamDTO> paramDTOList = JSONObject.parseArray(value, PayChannelParamDTO.class);
            return paramDTOList;
        }

        //根据应用id和平台服务类型code获取应用绑定服务类型的id
        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId, platformChannel);
        if (appPlatformChannelId == null) {
            throw new BusinessException(CommonErrorCode.E_110006);
        }
        //获取支付渠道参数
        List<PayChannelParam> payChannelParamList = payChannelParamMapper.selectList(new LambdaQueryWrapper<PayChannelParam>()
                .eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
        List<PayChannelParamDTO> payChannelParamDTOList = PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParamList);
        return payChannelParamDTOList;
    }




}
